package com.executor.gateway.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;
import java.util.List;

/**
 * 增强的Swagger配置类
 * 提供完整的API文档配置和安全认证配置
 * 
 * @author miaoguoxin
 * @date 2024/01/01
 */
@Configuration
@EnableSwagger2
public class EnhancedSwaggerConfiguration {

    @Value("${swagger.enabled:true}")
    private boolean swaggerEnabled;

    @Value("${swagger.title:Executor API Gateway}")
    private String title;

    @Value("${swagger.description:Executor API Gateway - 高性能微服务网关}")
    private String description;

    @Value("${swagger.version:1.0.0}")
    private String version;

    @Value("${swagger.contact.name:miaoguoxin}")
    private String contactName;

    @Value("${swagger.contact.email:miaoguoxin@example.com}")
    private String contactEmail;

    @Value("${swagger.contact.url:https://github.com/miaoguoxin}")
    private String contactUrl;

    /**
     * 网关管理API文档
     */
    @Bean
    public Docket gatewayManagementApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .enable(swaggerEnabled)
                .groupName("网关管理API")
                .apiInfo(gatewayApiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.executor.gateway.controller"))
                .paths(PathSelectors.any())
                .build()
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts());
    }

    /**
     * 监控API文档
     */
    @Bean
    public Docket monitoringApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .enable(swaggerEnabled)
                .groupName("监控API")
                .apiInfo(monitoringApiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.executor.gateway.controller"))
                .paths(PathSelectors.regex("/monitoring.*|/actuator.*"))
                .build()
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts());
    }

    /**
     * 配置管理API文档
     */
    @Bean
    public Docket configurationApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .enable(swaggerEnabled)
                .groupName("配置管理API")
                .apiInfo(configApiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.executor.gateway.controller"))
                .paths(PathSelectors.regex("/config.*"))
                .build()
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts());
    }

    /**
     * 网关API信息
     */
    private ApiInfo gatewayApiInfo() {
        return new ApiInfoBuilder()
                .title(title + " - 网关管理")
                .description("提供网关路由管理、API配置等功能的REST API接口")
                .version(version)
                .contact(new Contact(contactName, contactUrl, contactEmail))
                .license("Apache License 2.0")
                .licenseUrl("https://www.apache.org/licenses/LICENSE-2.0")
                .termsOfServiceUrl("https://example.com/terms")
                .build();
    }

    /**
     * 监控API信息
     */
    private ApiInfo monitoringApiInfo() {
        return new ApiInfoBuilder()
                .title(title + " - 监控管理")
                .description("提供网关监控、健康检查、指标查询等功能的REST API接口")
                .version(version)
                .contact(new Contact(contactName, contactUrl, contactEmail))
                .license("Apache License 2.0")
                .licenseUrl("https://www.apache.org/licenses/LICENSE-2.0")
                .termsOfServiceUrl("https://example.com/terms")
                .build();
    }

    /**
     * 配置API信息
     */
    private ApiInfo configApiInfo() {
        return new ApiInfoBuilder()
                .title(title + " - 配置管理")
                .description("提供动态路由配置、API配置管理等功能的REST API接口")
                .version(version)
                .contact(new Contact(contactName, contactUrl, contactEmail))
                .license("Apache License 2.0")
                .licenseUrl("https://www.apache.org/licenses/LICENSE-2.0")
                .termsOfServiceUrl("https://example.com/terms")
                .build();
    }

    /**
     * 安全认证配置
     */
    private List<SecurityScheme> securitySchemes() {
        List<SecurityScheme> securitySchemes = new ArrayList<>();
        
        // JWT认证
        securitySchemes.add(new ApiKey("JWT", "Authorization", "header"));
        
        // Basic认证
        securitySchemes.add(new BasicAuth("BasicAuth"));
        
        return securitySchemes;
    }

    /**
     * 安全上下文配置
     */
    private List<SecurityContext> securityContexts() {
        List<SecurityContext> securityContexts = new ArrayList<>();
        
        // JWT认证上下文
        securityContexts.add(SecurityContext.builder()
                .securityReferences(jwtSecurityReferences())
                .forPaths(PathSelectors.regex("/config.*|/monitoring.*"))
                .build());
        
        return securityContexts;
    }

    /**
     * JWT安全引用
     */
    private List<SecurityReference> jwtSecurityReferences() {
        List<SecurityReference> securityReferences = new ArrayList<>();
        
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        
        securityReferences.add(new SecurityReference("JWT", authorizationScopes));
        
        return securityReferences;
    }
}